cmake_minimum_required(VERSION 3.10)

project(Template)

file(GLOB SRCS
    ${PROJECT_SOURCE_DIR}/app/*.cpp
    ${PROJECT_SOURCE_DIR}/app/BLE/*.cpp
    ${PROJECT_SOURCE_DIR}/app/MotorController/*.cpp
    ${PROJECT_SOURCE_DIR}/app/Configuration/*.cpp
    ${PROJECT_SOURCE_DIR}/app/fs/*.cpp
    ${PROJECT_SOURCE_DIR}/app/fs/eeprom/*.cpp
    ${PROJECT_SOURCE_DIR}/app/fs/fatfs/*.c
    ${PROJECT_SOURCE_DIR}/app/fs/fatfs/*.cpp
    ${PROJECT_SOURCE_DIR}/app/fs/sdcard/*.cpp
    ${PROJECT_SOURCE_DIR}/system/*.c
    ${PROJECT_SOURCE_DIR}/system/std_periph_driver/src/*.c
    ${PROJECT_SOURCE_DIR}/app/CommProtocol/*.cpp
    ${PROJECT_SOURCE_DIR}/app/OTA/updater/*.c
    ${PROJECT_SOURCE_DIR}/app/OTA/image_loader/*.c
    ${PROJECT_SOURCE_DIR}/app/Fault_Info/*.cpp   
    ${PROJECT_SOURCE_DIR}/app/driver/*.cpp      
)

include_directories(
    ${PROJECT_SOURCE_DIR}/app
    ${PROJECT_SOURCE_DIR}/app/BLE
    ${PROJECT_SOURCE_DIR}/app/MotorController
    ${PROJECT_SOURCE_DIR}/app/Configuration
    ${PROJECT_SOURCE_DIR}/app/fs
    ${PROJECT_SOURCE_DIR}/app/fs/eeprom
    ${PROJECT_SOURCE_DIR}/app/fs/fatfs
    ${PROJECT_SOURCE_DIR}/app/fs/sdcard
    ${PROJECT_SOURCE_DIR}/system
    ${PROJECT_SOURCE_DIR}/system/std_periph_driver/inc
    ${PROJECT_SOURCE_DIR}/system/platform/cmsis
    ${PROJECT_SOURCE_DIR}/app/CommProtocol
    ${PROJECT_SOURCE_DIR}/app/OTA/updater
    ${PROJECT_SOURCE_DIR}/app/OTA/image_loader
    ${PROJECT_SOURCE_DIR}/app/OTA
    ${PROJECT_SOURCE_DIR}/app/Fault_Info
    ${PROJECT_SOURCE_DIR}/app/driver
)

set(STARTUP_FILE ${PROJECT_SOURCE_DIR}/startup.s)

set(LINKER_SCRIPT ${PROJECT_SOURCE_DIR}/link.ld)

set(LIBS "-lm -lstdc++ -lc")

enable_language(ASM)

# 设置交叉编译工具链

set(CROSS_COMPILER_PREFIX /home/jiayi/Tools/arm/arm-gnu-toolchain-13.3.rel1-x86_64-arm-none-eabi/bin/)

set(CMAKE_C_COMPILER ${CROSS_COMPILER_PREFIX}arm-none-eabi-gcc)
set(CMAKE_CXX_COMPILER ${CROSS_COMPILER_PREFIX}arm-none-eabi-g++)
set(CMAKE_ASM_COMPILER ${CROSS_COMPILER_PREFIX}arm-none-eabi-gcc)
set(CMAKE_OBJCOPY ${CROSS_COMPILER_PREFIX}arm-none-eabi-objcopy)
set(CMAKE_SIZE ${CROSS_COMPILER_PREFIX}arm-none-eabi-size)

set(MCU_FLAGS "-mcpu=cortex-m3 -mthumb")

set(COMPILE_MARCOS "-DAPM32A10X_HD")

# set(CMAKE_ASM_FLAGS "${COMPILE_MARCOS} ${MCU_FLAGS} -O0 -Wall -fdata-sections -ffunction-sections")
# set(CMAKE_C_FLAGS "${COMPILE_MARCOS} ${MCU_FLAGS} -O0 -Wall -fdata-sections -ffunction-sections")
# set(CMAKE_CXX_FLAGS "${COMPILE_MARCOS} ${MCU_FLAGS} -O0  -Wall -fdata-sections -ffunction-sections")

# set(CMAKE_ASM_FLAGS "${MCU_FLAGS} -O2 -Wall -fdata-sections -ffunction-sections")
# set(CMAKE_C_FLAGS "${MCU_FLAGS} -O2 -Wall -fdata-sections -ffunction-sections")
# set(CMAKE_CXX_FLAGS "${MCU_FLAGS} -O2  -Wall -fdata-sections -ffunction-sections")

set(CMAKE_ASM_FLAGS "${MCU_FLAGS} -O1 -Wall -fdata-sections -ffunction-sections")
set(CMAKE_C_FLAGS "${MCU_FLAGS} -O1 -Wall -fdata-sections -ffunction-sections")
set(CMAKE_CXX_FLAGS "${MCU_FLAGS} -O1  -Wall -fdata-sections -ffunction-sections")
# set(CMAKE_EXE_LINKER_FLAGS "${MCU_FLAGS} -T ${LINKER_SCRIPT} -O0 -specs=nano.specs -specs=nosys.specs ${LIBS} -Wl,-Map=${PROJECT_NAME}.map,--cref -Wl,--gc-sections -Wl,-u_printf_float")
set(CMAKE_EXE_LINKER_FLAGS "${MCU_FLAGS} -T ${LINKER_SCRIPT} -O1 -specs=nano.specs -specs=nosys.specs ${LIBS} -Wl,-Map=${PROJECT_NAME}.map,--cref -Wl,--gc-sections -Wl,-u_printf_float")


# 定义一个函数来创建或导入库
function(create_or_import_library LIB_NAME SRC_FILE LIB_PATH)
    file(GLOB LIB_SRCS ${SRC_FILE})
    if(EXISTS ${SRC_FILE})
        add_library(${LIB_NAME} STATIC ${LIB_SRCS})
        set_target_properties(${LIB_NAME} PROPERTIES
            ARCHIVE_OUTPUT_DIRECTORY ${LIB_PATH}
            OUTPUT_NAME ${LIB_NAME}
        )
    elseif(EXISTS ${LIB_PATH}/lib${LIB_NAME}.a)
        add_library(${LIB_NAME} STATIC IMPORTED)
        set_target_properties(${LIB_NAME} PROPERTIES
            IMPORTED_LOCATION ${LIB_PATH}/lib${LIB_NAME}.a
        )
    else()
        message(FATAL_ERROR "Neither ${SRC_FILE} nor ${LIB_PATH}/lib${LIB_NAME}.a exists. Cannot create or link the ${LIB_NAME} library.")
    endif()
endfunction()


create_or_import_library(CommProtocol ${PROJECT_SOURCE_DIR}/app/CommProtocol/CommProtocol.cpp ${PROJECT_SOURCE_DIR}/app/CommProtocol)
create_or_import_library(ProtocolImpl ${PROJECT_SOURCE_DIR}/app/CommProtocol/Protocol_impl.cpp ${PROJECT_SOURCE_DIR}/app/CommProtocol)
create_or_import_library(Configuration ${PROJECT_SOURCE_DIR}/app/Configuration/Configuration.cpp ${PROJECT_SOURCE_DIR}/app/Configuration)
create_or_import_library(MotorController ${PROJECT_SOURCE_DIR}/app/MotorController/MotorController.cpp ${PROJECT_SOURCE_DIR}/app/MotorController)
create_or_import_library(PIDController ${PROJECT_SOURCE_DIR}/app/MotorController/PIDController.cpp ${PROJECT_SOURCE_DIR}/app/MotorController)
create_or_import_library(ImageLoader ${PROJECT_SOURCE_DIR}/app/OTA/image_loader/image_loader.c ${PROJECT_SOURCE_DIR}/app/OTA/image_loader)
create_or_import_library(Updater ${PROJECT_SOURCE_DIR}/app/OTA/updater/updater.c ${PROJECT_SOURCE_DIR}/app/OTA/updater)

add_executable(${PROJECT_NAME}.elf ${STARTUP_FILE} ${SRCS})

target_link_libraries(${PROJECT_NAME}.elf CommProtocol)
target_link_libraries(${PROJECT_NAME}.elf ProtocolImpl)
target_link_libraries(${PROJECT_NAME}.elf Configuration)
target_link_libraries(${PROJECT_NAME}.elf MotorController)
target_link_libraries(${PROJECT_NAME}.elf PIDController)
target_link_libraries(${PROJECT_NAME}.elf ImageLoader)
target_link_libraries(${PROJECT_NAME}.elf Updater)
add_custom_command(TARGET ${PROJECT_NAME}.elf POST_BUILD
COMMENT "Building binary file and hex file..."
COMMAND ${CMAKE_OBJCOPY} -Obinary ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.elf ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.bin
COMMAND ${CMAKE_OBJCOPY} -Oihex ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.elf ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.hex
)

add_custom_command(TARGET ${PROJECT_NAME}.elf POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.bin ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.bin
COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.hex ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.hex
COMMAND ${CMAKE_SIZE} --format=berkeley ${PROJECT_NAME}.elf ${PROJECT_NAME}.hex
COMMENT "Invoking: Cross ARM GNU Print Size"
)

